home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1992 The Geometry Center; University of Minnesota
- 1300 South Second Street; Minneapolis, MN 55454, USA;
-
- This file is part of geomview/OOGL. geomview/OOGL is free software;
- you can redistribute it and/or modify it only under the terms given in
- the file COPYING, which you should have received along with this file.
- This and other related software may be obtained via anonymous ftp from
- geom.umn.edu; email: software@geom.umn.edu. */
-
- /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
-
- #include <ctype.h>
- #include "sl2c.h" /* in case file has elements of SL(2,C) */
- #include "discgrpP.h"
- #include <string.h>
- #include "mgP.h"
- #include "streampool.h"
- #include "transobj.h"
- #include "handleP.h"
-
- #define DG_GROUPNAME 1
- #define DG_COMMENT 2
- #define DG_ATTRIBUTE 3
- #define DG_MODEL 4
- #define DG_NGENS 5
- #define DG_NELS 6
- #define DG_GENS 7
- #define DG_ELS 8
- #define DG_DIMN 9
- #define DG_CAMGEOM 10
- #define DG_GEOM 11
- #define DG_CAMGEOMFILE 12
- #define DG_GEOMFILE 13
- #define DG_WAFILE 14
- #define DG_MATRIXGROUP 15
- #define DG_CPOINT 16
- #define DG_ENUMDEPTH 17
- #define DG_ENUMDIST 18
- #define DG_DSPYATTR 19
- #define DG_SCALE 20
- #define DG_C2M 21
- #define DG_NUMKEYWORDS 23 /* 2 redundant keywords */
-
- keytokenpair keytokenlist[] = {
- "group", DG_GROUPNAME,
- "comment", DG_COMMENT,
- "attribute", DG_ATTRIBUTE,
- "model", DG_MODEL,
- "ngens", DG_NGENS,
- "nels", DG_NELS,
- "gens", DG_GENS,
- "els", DG_ELS,
- "dimn", DG_DIMN,
- "dimension", DG_DIMN,
- "camgeom", DG_CAMGEOM,
- "geom", DG_GEOM,
- "camgeomfile", DG_CAMGEOMFILE,
- "geomfile", DG_GEOMFILE,
- "wafile", DG_WAFILE,
- "matrixgroup", DG_MATRIXGROUP,
- "mgroup", DG_MATRIXGROUP,
- "cpoint", DG_CPOINT,
- "enumdepth", DG_ENUMDEPTH,
- "enumdist", DG_ENUMDIST,
- "display", DG_DSPYATTR,
- "scale", DG_SCALE,
- "cam2model", DG_C2M
- };
-
- keytokenpair attr_list[DG_NUM_ATTR] = {
- "hyperbolic", DG_HYPERBOLIC,
- "euclidean", DG_EUCLIDEAN,
- "spherical", DG_SPHERICAL,
- "finite", DG_FINITE,
- "transposed", DG_TRANSPOSED,
- "conformalball", DG_CONFORMALBALL,
- "upperhalfspace", DG_UPPERHALFSPACE,
- "projective", DG_PROJECTIVEMODEL
- };
-
- keytokenpair dspyattr_list[DG_NUM_DSPYATTR] = {
- "centercam", DG_CENTERCAM,
- "zcull", DG_ZCULL,
- "drawcam", DG_DRAWCAM,
- "drawdirdom", DG_DRAWDIRDOM,
- "drawgeom", DG_DRAWGEOM
- };
-
- /* Name can be {GL | SL | SO } ( {n},{k},{R | C} ) */
- matrixgroup cgroup = { DG_GENERAL | DG_REAL, 4, 0};
-
- static char delims[] = "%{}();";
- static char errfmt[] = "Reading discrete group from \"%s\": %s";
-
- static int
- token_from_string(char *s, keytokenpair *kl, int n)
- {
- int i;
- for (i=0; i<n; ++i) {
- if (strcasecmp(s, kl[i].key) == 0)
- return (kl[i].token);
- }
- return (0);
- }
-
-
- /* following gets the next %keyword from file.
- returns 0 if EOF, otherwise 1 */
- static int
- get_keyword(fp, keyword, fname)
- FILE *fp;
- char keyword[];
- char *fname;
- {
- char t;
-
- t = fnextc(fp, 0);
- if (t == '\377') { /* EOF */
- getc(fp);
- return(0);
- }
-
- else if (t == '}') { /* end of discgrp description? */
- return(0);
- }
-
- if (t != '(') {
- OOGLSyntax(fp,"Reading discrete group from \"%s\": expected (", fname);
- return(0);
- }
- /* discard 't': it's OK */
- getc(fp);
- sprintf(keyword, "%.31s", fdelimtok(delims, fp, 0));
- return 1;
- }
-
- static int
- get_matching_parenthesis(FILE *fp, char *fname)
- {
- char t;
- t = fnextc(fp, 0);
- if (t == EOF) return(0);
- if (t != ')') {
- OOGLSyntax(fp,"Reading discrete group from \"%s\": expected matching )", fname);
- return(0);
- }
- getc(fp);
- return(1);
- }
-
- static FILE *
- included_file(fp)
- FILE *fp;
- {
- char *name;
-
- if (fnextc(fp, 0) == '<') /* read from file */
- {
- name = fdelimtok(delims, fp, 0);
- OOGLError(1,"Discrete groups: including files not implemented");
- return(NULL);
- }
- return(NULL);
- }
-
- static int
- parse_group_name(char *gname)
- {
- char *gptr = gname;
-
- cgroup.attributes = DG_GENERAL | DG_REAL; /* type of entry */
- cgroup.dimn = 4; /* dimension of matrices */
- cgroup.sig = 0; /* signature of quadratic form */
-
- }
-
- static ColorA white = {1,1,1,.75};
-
- static void
- get_el_list( DiscGrp *discgrp, DiscGrpElList *dgellist, FILE *fp, char *fname)
- {
- int i;
- char *name, c;
-
- if (included_file(fp)) /* read from file */
- {
- }
-
- for (i=0; i<dgellist->num_el; ++i) {
- dgellist->el_list[i].attributes = 0;
- dgellist->el_list[i].color = white;
- dgellist->el_list[i].inverse = NULL;
- c = fnextc(fp, 0);
- /* get the name if it's alphabetic */
- if ( c >= 'A' && c <= 'z' )
- {
- name = fdelimtok(delims, fp, 0);
- if (strlen(name) > DG_WORDLENGTH) {
- OOGLSyntax(fp,"Reading discrete group from \"%s\": Words limited to length %d", fname, DG_WORDLENGTH);
- return;
- }
- strcpy(dgellist->el_list[i].word, name);
- }
- else { /* make up a name for this gen */
- dgellist->el_list[i].word[0] = 'a' + i;
- dgellist->el_list[i].word[1] = 0;
- }
-
-
- switch(discgrp->attributes & DG_MODEL_BITS){
- case DG_CONFORMALBALL:
- OOGLSyntax(fp,errfmt,fname,"Unimplemented conformal model");
- break;
-
- case DG_UPPERHALFSPACE:
- {
- lin_frac mylf;
- proj_matrix mypm;
- int k,m;
- for (k=0; k<2; ++k) for (m=0; m<2; ++m)
- fscanf(fp,"%lf%lf",&mylf[k][m].real, &mylf[k][m].imag);
- sl2c_to_proj(mylf, mypm);
- for (k=0; k<4; ++k) for (m=0; m<4; ++m)
- dgellist->el_list[i].tform[k][m] = mypm[k][m];
- }
- break;
-
- default:
- if (fgettransform(fp,1,(float *)dgellist->el_list[i].tform,0) != 1) {
- OOGLSyntax(fp,errfmt,fname,"Error reading generator");
- return;
- }
- if (discgrp->attributes & DG_TRANSPOSED)
- TmTranspose(dgellist->el_list[i].tform, discgrp->big_list->el_list[i].tform);
- break;
- }
- }
- }
-
- Geom *
- DiscGrpImport(Pool *p)
- {
- char *name, *fname, t;
- char keyword[DG_KEYWORDSIZE];
- DiscGrp *discgrp;
- int i;
- FILE *wafp, *fp;
- char *expect;
-
- if(p == NULL || (fp = p->inf) == NULL)
- return 0;
-
- /* check for 'DISCGRP' at head of file */
- if(fexpectstr(fp, "DISCGRP"))
- return(NULL);
-
- /* now the parentheses begin */
- if ((t = fnextc(fp, 0)) != '(')
- return(NULL);
-
- discgrp = (DiscGrp*)GeomCreate("discgrp",CR_END);
-
- while (get_keyword(fp, keyword,p->poolname)) {
-
- switch ( token_from_string(keyword, keytokenlist,sizeof(keytokenlist)/sizeof(keytokenpair) )) {
-
- case DG_WAFILE:
- name = fdelimtok(delims, fp, 0);
- fname = findfile(PoolName(p), name);
- if(fname == NULL || (wafp = fopen(fname, "r")) == NULL) {
- OOGLSyntax(fp,
- "Reading discrete group from \"%s\": can't open wafile \"%s\"",
- p->poolname, name);
- return(NULL);
- }
- discgrp->fsa = OOGLNew(wa);
- fsaparse(wafp, discgrp->fsa);
- fclose(wafp);
- break;
-
- case DG_DSPYATTR:
- name = fdelimtok(delims, fp, 0);
- discgrp->flag |= token_from_string(name, dspyattr_list,sizeof(dspyattr_list)/sizeof(keytokenpair));
- break;
-
- case DG_ATTRIBUTE:
- case DG_MODEL:
- name = fdelimtok(delims, fp, 0);
- discgrp->attributes |= token_from_string(name, attr_list,sizeof(attr_list)/sizeof(keytokenpair));
- break;
-
- case DG_COMMENT:
- discgrp->comment = strdup(fdelimtok(delims, fp, 0));
- break;
-
- case DG_MATRIXGROUP:
- parse_group_name(fdelimtok(delims, fp, 0));
- break;
-
- case DG_SCALE:
- if(fgetnf(fp, 1, &discgrp->scale, 0) <= 0) {
- OOGLSyntax(fp,errfmt, p->poolname, "Invalid scale");
- return(NULL);
- }
- break;
-
-
- case DG_C2M:
- discgrp->c2m = (float (*)[4])OOGLNewNE(float, 16, "Transform");
- if (fgettransform(fp,1,(float *)discgrp->c2m,0) != 1) {
- OOGLSyntax(fp,errfmt,p->poolname,"Error reading cam2model");
- return(NULL);
- }
- break;
-
- case DG_ENUMDEPTH:
- if(fgetni(fp, 1, &discgrp->enumdepth, 0) <= 0) {
- OOGLSyntax(fp,errfmt, p->poolname, "Invalid enumdepth");
- return(NULL);
- }
- break;
-
- case DG_ENUMDIST:
- if(fgetnf(fp, 1, &discgrp->enumdist, 0) <= 0) {
- OOGLSyntax(fp,errfmt, p->poolname, "Invalid enumdist");
- return(NULL);
- }
- break;
-
- case DG_CPOINT:
- if(fgetnf(fp, 4, (float *)&discgrp->cpoint, 0) <= 0) {
- OOGLSyntax(fp,errfmt, p->poolname, "Invalid Cpoint");
- return(NULL);
- }
- break;
-
- case DG_CAMGEOM:
- expect = "camgeometry";
- if(!GeomStreamIn(p, &discgrp->camgeomhandle, &discgrp->camgeom))
- goto failed;
- if(discgrp->camgeomhandle)
- HandleRegister(&discgrp->camgeomhandle, (Ref *)discgrp,
- &discgrp->camgeom, HandleUpdRef);
-
- break;
-
- case DG_ELS:
- discgrp->big_list->mgroup = cgroup;
- get_el_list(discgrp, discgrp->big_list, fp, p->poolname);
- discgrp->flag |= DG_SAVEBIGLIST;
- break;
-
- case DG_GROUPNAME:
- discgrp->name = strdup(fdelimtok(delims, fp, 0));
- break;
-
- case DG_GENS:
- {
- int i;
- static char name[2] = "a";
- discgrp->gens->mgroup = cgroup;
- get_el_list(discgrp, discgrp->gens, fp, p->poolname);
- /* make up names for the generators if not given */
- if (strcmp(discgrp->gens->el_list[0].word, "") == 0) {
- for (i=0; i<discgrp->gens->num_el; ++i) {
- strcpy(discgrp->gens->el_list[i].word,name);
- name[0]++;
- }
- }
- }
-
- break;
-
- case DG_GEOM:
- expect = "geometry";
- if(!GeomStreamIn(p, &discgrp->geomhandle, &discgrp->geom))
- goto failed;
- if(discgrp->geomhandle)
- HandleRegister(&discgrp->geomhandle, (Ref *)discgrp,
- &discgrp->geom, HandleUpdRef);
-
- break;
-
- case DG_DIMN:
- if(fgetni(fp, 1, &discgrp->dimn, 0) <= 0 ||
- discgrp->dimn > 4) {
- OOGLSyntax(fp,errfmt, p->poolname, "Invalid Dimension");
- return(NULL);
- }
- cgroup.dimn = discgrp->dimn+1; /* default matrix group */
- break;
-
- case DG_NGENS:
- {
- int ngens;
- if(fgetni(fp, 1, &ngens, 0) <= 0 || ngens <= 0) {
- OOGLSyntax(fp,errfmt,p->poolname, "Invalid generator count");
- return(NULL);
- }
- discgrp->gens = OOGLNewE(DiscGrpElList, "DiscGrp gens");
- discgrp->gens->num_el = ngens;
- discgrp->gens->el_list = OOGLNewNE(DiscGrpEl,
- discgrp->gens->num_el, "DiscGrp gens elem list");
- }
- break;
-
- case DG_NELS:
- {
- int nels;
- if(fgetni(fp, 1, &nels, 0) <= 0 || nels <= 0) {
- OOGLSyntax(fp,errfmt,p->poolname, "Invalid generator count");
- return(NULL);
- }
- discgrp->big_list = OOGLNewE(DiscGrpElList, "DiscGrp el_list");
- discgrp->big_list->num_el = nels;
- discgrp->big_list->el_list = OOGLNewNE(DiscGrpEl,
- discgrp->big_list->num_el, "DiscGrp elem list");
- }
- break;
- failed:
- OOGLSyntax(fp, "Couldn't read DISCGRP in \"%s\": expected %s",
- PoolName(p), expect);
- break;
-
- default:
- OOGLError(1,"Bad keyword DiscGrpFLoad %s",keyword);
- break;
- }
- if ( !(get_matching_parenthesis(fp,p->poolname))) break;
- }
-
- /* make sure the generator list includes all inverses */
- DiscGrpAddInverses(discgrp);
-
- /*
- if (discgrp->geom == NULL)
- {
- discgrp->flag |= DG_DRAWDIRDOM;
- DiscGrpSetupDirdom(discgrp);
- discgrp->ddgeom = DiscGrpDirDom(discgrp);
- }
- */
-
- if (discgrp->big_list == NULL)
- {
- DiscGrpInitStandardConstraint(discgrp->enumdepth, discgrp->enumdist, discgrp->enumdist);
- discgrp->big_list = DiscGrpEnum(discgrp, DiscGrpStandardConstraint);
- }
-
- return(( Geom *) discgrp);
- }
-